{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "vscode": {
     "languageId": "raw"
    }
   },
   "source": [
    "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/klavis-ai/klavis/blob/main/examples/claude/Use_Klavis_with_Claude.ipynb)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "vscode": {
     "languageId": "raw"
    }
   },
   "source": [
    "# Claude + Klavis AI Integration\n",
    "\n",
    "This tutorial demonstrates how to use Anthropic's Claude with tool use (function calling) with Klavis MCP (Model Context Protocol) servers.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "vscode": {
     "languageId": "raw"
    }
   },
   "source": [
    "## Prerequisites\n",
    "\n",
    "- **Anthropic API key** - Get at [console.anthropic.com](https://console.anthropic.com/)\n",
    "- **Klavis API key** - Get at [klavis.ai](https://klavis.ai/)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Note: you may need to restart the kernel to use updated packages.\n"
     ]
    }
   ],
   "source": [
    "# Install the required packages\n",
    "%pip install -qU anthropic klavis"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import json\n",
    "from anthropic import Anthropic\n",
    "from klavis import Klavis\n",
    "from klavis.types import McpServerName, ToolFormat\n",
    "\n",
    "# Set environment variables\n",
    "os.environ[\"ANTHROPIC_API_KEY\"] = \"YOUR_ANTHROPIC_API_KEY\"  # Replace with your actual Anthropic API key\n",
    "os.environ[\"KLAVIS_API_KEY\"] = \"YOUR_KLAVIS_API_KEY\"  # Replace with your actual Klavis API key\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "vscode": {
     "languageId": "raw"
    }
   },
   "source": [
    "## Case Study 1 : Claude + YouTube MCP Server\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "vscode": {
     "languageId": "raw"
    }
   },
   "source": [
    "#### Step 1 - Create YouTube MCP Server using Klavis\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "klavis_client = Klavis(api_key=os.getenv(\"KLAVIS_API_KEY\"))\n",
    "\n",
    "youtube_mcp_instance = klavis_client.mcp_server.create_server_instance(\n",
    "    server_name=McpServerName.YOUTUBE,\n",
    "    user_id=\"1234\",\n",
    ")\n",
    "\n",
    "# print(f\"\ud83d\udd17 YouTube MCP server created at: {youtube_mcp_instance.server_url}, and the instance id is {youtube_mcp_instance.instance_id}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "vscode": {
     "languageId": "raw"
    }
   },
   "source": [
    "#### Step 2 - Create general method to use MCP Server with Claude\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def claude_with_mcp_server(mcp_server_url: str, user_query: str):\n",
    "    claude_client = Anthropic(api_key=os.getenv(\"ANTHROPIC_API_KEY\"))\n",
    "\n",
    "    messages = [\n",
    "        {\"role\": \"user\", \"content\": f\"{user_query}\"}\n",
    "    ]\n",
    "    \n",
    "    mcp_server_tools = klavis_client.mcp_server.list_tools(\n",
    "        server_url=mcp_server_url,\n",
    "        format=ToolFormat.ANTHROPIC,\n",
    "    )\n",
    "    \n",
    "    response = claude_client.messages.create(\n",
    "        model=\"claude-sonnet-4-20250514\",\n",
    "        max_tokens=4000,\n",
    "        system=\"You are a helpful assistant. Use the available tools to answer the user's question.\",\n",
    "        messages=messages,\n",
    "        tools=mcp_server_tools.tools\n",
    "    )\n",
    "    \n",
    "    messages.append({\"role\": \"assistant\", \"content\": response.content})\n",
    "\n",
    "    if response.stop_reason == \"tool_use\":\n",
    "        tool_results = []\n",
    "        \n",
    "        for content_block in response.content:\n",
    "            if content_block.type == \"tool_use\":\n",
    "                function_name = content_block.name\n",
    "                function_args = content_block.input\n",
    "                \n",
    "                print(f\"\ud83d\udd27 Calling: {function_name}, with args: {function_args}\")\n",
    "                \n",
    "                result = klavis_client.mcp_server.call_tools(\n",
    "                    server_url=mcp_server_url,\n",
    "                    tool_name=function_name,\n",
    "                    tool_args=function_args,\n",
    "                )\n",
    "                \n",
    "                tool_results.append({\n",
    "                    \"type\": \"tool_result\",\n",
    "                    \"tool_use_id\": content_block.id,\n",
    "                    \"content\": str(result)\n",
    "                })\n",
    "        \n",
    "        messages.append({\"role\": \"user\", \"content\": tool_results})\n",
    "            \n",
    "        final_response = claude_client.messages.create(\n",
    "            model=\"claude-3-5-sonnet-20241022\",\n",
    "            max_tokens=4000,\n",
    "            system=\"You are a helpful assistant. Use the available tools to answer the user's question.\",\n",
    "            messages=messages,\n",
    "            tools=mcp_server_tools.tools\n",
    "        )\n",
    "        \n",
    "        return final_response.content[0].text\n",
    "    else:\n",
    "        return response.content[0].text\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "vscode": {
     "languageId": "raw"
    }
   },
   "source": [
    "#### Step 3 - Summarize your favorite video!\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\ud83d\udd27 Calling: get_youtube_video_transcript, with args: {'url': 'https://www.youtube.com/watch?v=LCEmiRjPEtQ'}\n",
      "Based on the video details, I'll provide a comprehensive summary of Andrej Karpathy's keynote speech \"Software Is Changing (Again)\" at AI Startup School. Here's a breakdown by key segments:\n",
      "\n",
      "1. Introduction and Software Evolution (0:00-04:40)\n",
      "- The talk begins with an overview of how software is fundamentally changing\n",
      "- Discusses the evolution from Software 1.0 to 3.0\n",
      "- Karpathy positions this as a major paradigm shift in software development\n",
      "\n",
      "2. Programming in English & Software 3.0 (04:40-06:10)\n",
      "- Introduces the concept of programming in natural language\n",
      "- Explains how LLMs are changing the programming paradigm\n",
      "- Highlights the transition to Software 3.0 where English becomes the programming interface\n",
      "\n",
      "3. LLMs as Computing Infrastructure (06:10-14:39)\n",
      "- Discusses three key aspects of LLMs:\n",
      "  - As utilities\n",
      "  - As fabrication facilities (fabs)\n",
      "  - As operating systems\n",
      "- Draws historical computing analogies, comparing current state to 1960s computing\n",
      "\n",
      "4. LLM Psychology (14:39-18:22)\n",
      "- Describes LLMs as \"people spirits\"\n",
      "- Explores their nature as stochastic simulations of people\n",
      "- Discusses their capabilities and limitations\n",
      "- Explains how they exhibit both superhuman abilities and human-like fallibilities\n",
      "\n",
      "5. Practical Applications (18:22-29:06)\n",
      "- Covers designing LLM applications with partial autonomy\n",
      "- Emphasizes the importance of human-AI collaboration\n",
      "- Shares lessons learned from Tesla Autopilot\n",
      "- Introduces the concept of \"autonomy sliders\"\n",
      "- Uses the Iron Man analogy to explain augmentation vs. agents approach\n",
      "\n",
      "6. Democratization of Programming (29:06-33:39)\n",
      "- Introduces \"Vibe Coding\" concept\n",
      "- Explains how LLMs make programming accessible to everyone\n",
      "- Discusses the implications of natural language programming\n",
      "\n",
      "7. Future Outlook (33:39-38:14)\n",
      "- Focuses on building for agents\n",
      "- Discusses future-ready digital infrastructure\n",
      "- Explains how to prepare for the next generation of software\n",
      "\n",
      "8. Conclusion (38:14-end)\n",
      "- Summarizes key points\n",
      "- Emphasizes that we're in the early stages (equivalent to 1960s) of LLM development\n",
      "- Calls to action for builders and developers\n",
      "\n",
      "Key Takeaways:\n",
      "- Software is undergoing a fundamental transformation with LLMs\n",
      "- Natural language is becoming the new programming interface\n",
      "- We're in the early stages of this technology, comparable to 1960s computing\n",
      "- LLMs have unique psychological properties that influence how we should work with them\n",
      "- The future of software development will be more accessible to non-programmers\n",
      "- There's a need to build infrastructure that's ready for AI agents\n",
      "\n",
      "The talk includes several valuable references and links, including Karpathy's original \"Software 2.0\" blog post from 2017 and recent writings on vibe coding and technology diffusion.\n"
     ]
    }
   ],
   "source": [
    "YOUTUBE_VIDEO_URL = \"https://www.youtube.com/watch?v=LCEmiRjPEtQ\"  # pick a video you like!\n",
    "\n",
    "result = claude_with_mcp_server(\n",
    "    mcp_server_url=youtube_mcp_instance.server_url, \n",
    "    user_query=f\"Please provide a complete summary of this YouTube video with timestamp: {YOUTUBE_VIDEO_URL}\"\n",
    ")\n",
    "\n",
    "print(result)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "vscode": {
     "languageId": "raw"
    }
   },
   "source": [
    "\u2705 Great! You've successfully created an AI agent that uses Claude's tool use with Klavis MCP servers to summarize YouTube videos!\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "vscode": {
     "languageId": "raw"
    }
   },
   "source": [
    "## Case Study 2 : Claude + Gmail MCP Server (OAuth needed)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\ud83d\udd10 Opening OAuth authorization for Gmail, if you are not redirected, please open the following URL in your browser: https://api.klavis.ai/oauth/gmail/authorize?instance_id=d9d482b3-433a-4330-9a8b-9548c0b0a326\n"
     ]
    }
   ],
   "source": [
    "import webbrowser\n",
    "\n",
    "gmail_mcp_server = klavis_client.mcp_server.create_server_instance(\n",
    "    server_name=McpServerName.GMAIL,\n",
    "    user_id=\"1234\",\n",
    ")\n",
    "\n",
    "webbrowser.open(gmail_mcp_server.oauth_url)\n",
    "\n",
    "print(f\"\ud83d\udd10 Opening OAuth authorization for Gmail, if you are not redirected, please open the following URL in your browser: {gmail_mcp_server.oauth_url}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\ud83d\udd27 Calling: send_email, with args: {'to': ['zihaolin@klavis.ai'], 'subject': 'Test Claude + Gmail MCP Server', 'body': 'Hello World from Claude!'}\n",
      "I've sent the email as requested with:\n",
      "- To: zihaolin@klavis.ai\n",
      "- Subject: Test Claude + Gmail MCP Server\n",
      "- Body: Hello World from Claude!\n",
      "\n",
      "The email was sent successfully. Is there anything else you'd like me to help you with?\n"
     ]
    }
   ],
   "source": [
    "EMAIL_RECIPIENT = \"zihaolin@klavis.ai\" # Replace with your email\n",
    "EMAIL_SUBJECT = \"Test Claude + Gmail MCP Server\"\n",
    "EMAIL_BODY = \"Hello World from Claude!\"\n",
    "\n",
    "result = claude_with_mcp_server(\n",
    "    mcp_server_url=gmail_mcp_server.server_url, \n",
    "    user_query=f\"Please send an email to {EMAIL_RECIPIENT} with subject {EMAIL_SUBJECT} and body {EMAIL_BODY}\"\n",
    ")\n",
    "\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "vscode": {
     "languageId": "raw"
    }
   },
   "source": [
    "## Summary\n",
    "\n",
    "This tutorial demonstrated how to integrate Anthropic's Claude with tool use capabilities with Klavis MCP servers to create powerful AI applications. We covered two practical examples:\n",
    "\n",
    "**\ud83c\udfa5 YouTube Integration**: Built an AI assistant that can automatically summarize YouTube videos by extracting transcripts and providing detailed, timestamped summaries.\n",
    "\n",
    "**\ud83d\udce7 Gmail Integration**: Created an AI-powered email assistant that can send emails through Gmail with OAuth authentication.\n",
    "\n",
    "### Key Takeaways:\n",
    "- **Easy Setup**: Klavis MCP servers can be created with just a few lines of code\n",
    "- **Claude Compatible**: All tools are formatted for seamless Claude tool use\n",
    "- **Versatile**: Support for both simple APIs (YouTube) and OAuth-authenticated services (Gmail)\n",
    "- **Scalable**: The same pattern can be applied to any of the MCP servers available in Klavis\n",
    "- **Advanced Reasoning**: Claude's superior reasoning capabilities make it excellent for complex analysis tasks\n",
    "\n",
    "**Happy building!** \ud83d\ude80\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}